package com.kitkat.daoImpl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.stereotype.Component;

import com.kitkat.dao.AbstractTokenDAO;


@Component
public class AbstractTokenDAOImpl<K,V> implements AbstractTokenDAO<K,V>{
	public static final long ExpirationTime = 60L*60L*24L*3L;
	@Autowired
	private RedisTemplate<K,V> redisTemplate;

	@Override
	public boolean set(final K key,final V value) {
		boolean result = this.redisTemplate.execute(new RedisCallback<Boolean>() {
			@Override
			public Boolean doInRedis(RedisConnection connection)
					throws DataAccessException {
				RedisSerializer<K> keySerializer = (RedisSerializer<K>) redisTemplate.getHashKeySerializer();
				RedisSerializer<V> valueSerializer = (RedisSerializer<V>) redisTemplate.getHashKeySerializer();
				final byte[] keyBytes = keySerializer.serialize(key);
				final byte[] valueBytes = valueSerializer.serialize(value);
				connection.setEx(keyBytes, ExpirationTime, valueBytes);
				return true;
			}
		});
		return result;
	}

	@Override
	public V get(final K key) {
		V result = this.redisTemplate.execute(new RedisCallback<V>() {
			@Override
			public V doInRedis(RedisConnection connection)
					throws DataAccessException {
				RedisSerializer<K> keySerializer = (RedisSerializer<K>) redisTemplate.getHashKeySerializer();
				RedisSerializer<V> valueSerializer = (RedisSerializer<V>) redisTemplate.getHashKeySerializer();
				byte[] keyBytes = keySerializer.serialize(key);
				if(connection.exists(keyBytes)){
					byte[] valueBytes = connection.get(keyBytes);
					return valueSerializer.deserialize(valueBytes);
				}
				return null;
			}
			
		});
		return result;
	}

	@Override
	public boolean delete(final K key) {
		Boolean result = this.redisTemplate.execute(new RedisCallback<Boolean>() {
			@Override
			public Boolean doInRedis(RedisConnection connection)
					throws DataAccessException {
				RedisSerializer<K> keySerializer = (RedisSerializer<K>) redisTemplate.getHashKeySerializer();
				RedisSerializer<V> valueSerializer = (RedisSerializer<V>) redisTemplate.getHashKeySerializer();
				byte[] keyBytes = keySerializer.serialize(key);
				if(connection.exists(keyBytes)){
					connection.del(keyBytes);
					return true;
				}
				return false;
			}
			
		});
		return result;
	}
}
